package cn.edu.xmu.oomall.customer.service;

import cn.edu.xmu.oomall.core.model.VoObject;
import cn.edu.xmu.oomall.core.util.JacksonUtil;
import cn.edu.xmu.oomall.core.util.ReturnNo;
import cn.edu.xmu.oomall.core.util.ReturnObject;
import cn.edu.xmu.oomall.customer.dao.AddressDao;
import cn.edu.xmu.oomall.customer.microservice.FreightService;
import cn.edu.xmu.oomall.customer.model.bo.Address;
import cn.edu.xmu.oomall.customer.model.po.AddressPo;
import cn.edu.xmu.oomall.customer.model.vo.AddressRetVo;
import cn.edu.xmu.oomall.customer.model.vo.AddressVo;
import cn.edu.xmu.oomall.customer.microservice.vo.SimpleRegionRetVo;
import cn.edu.xmu.privilegegateway.annotation.util.Common;
import cn.edu.xmu.privilegegateway.annotation.util.InternalReturnObject;

import java.util.ArrayList;
import java.util.List;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import static cn.edu.xmu.oomall.core.util.Common.decorateReturnObject;

@Service
/**
 * @author Jiazhe Yuan
 * @date 2021-12-14 12:31:22
 */
/**
 * @author Jiazhe Yuan
 * @time 2021-12-23 21:01:22
 * @info 处理openfeign的异常返回
 */
public class AddressService {

    @Autowired
    private AddressDao addressDao;

    @Autowired
    private FreightService freightService;

    /**
     * 最大地址数量限制
     */
    private static final int MAX_ADDRESS_NUM = 20;

    @Transactional(rollbackFor = Exception.class)
    public ReturnObject addNewAddress(Long creatorId, String creatorName, AddressVo addressVo) {
        ReturnObject<List<AddressPo>> addressPos = addressDao.getAllAddress(creatorId);
        if (addressPos.getData().size() >= MAX_ADDRESS_NUM) {
            return new ReturnObject<>(ReturnNo.ADDRESS_OUTLIMIT);
        }

        InternalReturnObject<SimpleRegionRetVo> ret = new InternalReturnObject<>();
        try {
            ret = freightService.getSimpleRegionById(addressVo.getRegionId());
        } catch (Exception e) {
        }

        Address address = Common.cloneVo(addressVo, Address.class);
        address.setBeDefault(false);
        address.setCustomerId(creatorId);
        ReturnObject returnObject = addressDao.addNewAddress(creatorId, creatorName, address);

        if (!returnObject.getCode().equals(ReturnNo.OK)) {
            return returnObject;
        }

        AddressPo addressPo = (AddressPo) returnObject.getData();
        AddressRetVo addressRetVo = Common.cloneVo(addressPo, AddressRetVo.class);
        addressRetVo.setBeDefault(addressPo.getBeDefault() != 0);
        SimpleRegionRetVo simpleRegionRetVo = new SimpleRegionRetVo();
        try {
            simpleRegionRetVo = (SimpleRegionRetVo) ret.getData();
        } catch (Exception e)  {
            System.out.println(e.getMessage());
        }
        addressRetVo.setRegion(simpleRegionRetVo);
        return new ReturnObject<>(addressRetVo);
    }

    @Transactional(rollbackFor = Exception.class)
    public ReturnObject getAllAddresses(Long customerId) {
        List<AddressPo> addressPos = (List<AddressPo>) addressDao.getAllAddress(customerId).getData();
        List<VoObject> addresses = new ArrayList<>();

        try {
            for (var tmp : addressPos) {
                AddressRetVo addressRetVo = Common.cloneVo(tmp, AddressRetVo.class);
                var ret = freightService.getSimpleRegionById(tmp.getRegionId());
                addressRetVo.setBeDefault(tmp.getBeDefault() != 0);
                SimpleRegionRetVo simpleRegionRetVo = (SimpleRegionRetVo) ret.getData();
                addressRetVo.setRegion(simpleRegionRetVo);
                addresses.add(addressRetVo);
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }

        return new ReturnObject(addresses);
    }

    @Transactional(rollbackFor = Exception.class)
    public ReturnObject setAddressDefault(Long customerId, String customerName, Long addressId) {
        ReturnObject ret = addressDao.setAddressDefault(customerId, customerName, addressId);
        return ret;
    }

    @Transactional(rollbackFor = Exception.class)
    public ReturnObject modifyAddress(Long customerId, String customerName, Long addressId, AddressVo addressVo) {
        ReturnObject ret = addressDao.modifyAddress(customerId, customerName, addressId, addressVo);
        return ret;
    }

    @Transactional(rollbackFor = Exception.class)
    public ReturnObject deleteAddress(Long customerId, Long addressId) {
        ReturnObject ret = addressDao.deleteAddress(customerId, addressId);
        return ret;
    }
}
